package org.jeecg.common.system.util;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CompleteMultipartUploadResult;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.UploadFileRequest;
import com.aliyun.oss.model.UploadFileResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;

/**
 * Created by ye on 2016/12/5.
 */
public class AliyunOssHelper {
    private static  final Logger log = LoggerFactory.getLogger(AliyunOssHelper.class);
    private static String endpoint = "http://oss-cn-shanghai.aliyuncs.com";
    private static String accessKeyId = "LTAI4GKBDKTDdNDxxHAyVzv7";
    private static String accessKeySecret = "7iicLwAr19pTf3XFiewFY2mwKmQARJ";
    private static String bucketName = "mcpicture";
    private static String visitPrefix = "http://b.file.ian9.cn/";
    // Object是OSS存储数据的基本单元，称为OSS的对象，也被称为OSS的文件。详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
    // Object命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
//    private static String firstKey = "test/my-first-key";

    private static OSSClient ossClient =null;
    static {
//        PropertyConfigurator.configure("conf/log4j.properties");
        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        //检查bucket是否存在。
        if (ossClient.doesBucketExist(bucketName)) {
            log.debug("您已经创建Bucket：" + bucketName + "。");
        } else {
            log.debug("您的Bucket不存在，创建Bucket：" + bucketName + "。");
            ossClient.createBucket(bucketName);
        }
    }

    /**
     * 获取文件的完整URL路径
     * @param key 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @return
     */
    public static String getUrlPath(String key){
        StringBuilder sb = new StringBuilder();
        sb.append("http://").append(bucketName).append(".").append(endpoint.substring(7)).append("/").append(key);
        return sb.toString();
    }

    /**
     * 获取文件的完整URL路径
     * @param key 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @return
     */
    public static String getVisitPath(String key){
        StringBuilder sb = new StringBuilder();
        sb.append(visitPrefix).append(key);
        return sb.toString();
    }

    /**
     * 获取文件路径
     * @param url 文件的完整URL路径
     * @return
     */
    public static String getKey(String url){
    	int urlLength = url.length();
    	StringBuilder sb = new StringBuilder();
        sb.append("http://").append(bucketName).append(".").append(endpoint.substring(7)).append("/");
        int sbLength = sb.length();
        if(urlLength < sbLength){
        	return null;
        }
        String key = url.substring(sbLength, urlLength);
        return key;
    }

    /**
     * 存储文件
     * @param key 文件路径,例comfile/2016/12/1111.jpg 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @param in  要上传的文件流
     * @return
     */
    public static  boolean put(String key,InputStream in){
        try {
            ossClient.putObject(bucketName, key, in);
        }catch (OSSException|ClientException e){
            log.warn("上传oss文件失败！ 文件KEY="+key,e);
            return false;
        }
        return true;
    }

    /**
     * 存储文件
     * @param key  文件路径,例comfile/2016/12/1111.jpg 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @param file 要上传的文件
     * @return
     */
    public static boolean put(String key,File file){
        try {
            ossClient.putObject(bucketName,key,file);
        }catch (OSSException|ClientException e){
            log.warn("上传oss文件失败！ 文件KEY="+key,e);
            return false;
        }
        return true;
    }
    
    /**
     * 上传文件并返回文件请求的URL
     * @param key  文件路径,例comfile/2016/12/1111.jpg 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @param in  要上传的文件流
     * @return
     */
    public static String upload(String key,InputStream in){
    	boolean flag = put(key, in);
    	if(flag){
    		return getUrlPath(key);
    	}
        return "";
    }

    /**
     * 断点续传文件
     * @param key  OSS文件路径
     * @param uploadFile 本地文件路径
     * @return
     */
    public static boolean partPut(String key,String uploadFile){
        try {
            UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, key);
            // 待上传的本地文件
            uploadFileRequest.setUploadFile(uploadFile);
            // 设置并发下载数，默认1
            uploadFileRequest.setTaskNum(5);
            // 设置分片大小，默认100KB
            uploadFileRequest.setPartSize(1024 * 1024 * 1);
            // 开启断点续传，默认关闭
            uploadFileRequest.setEnableCheckpoint(true);

            UploadFileResult uploadResult = ossClient.uploadFile(uploadFileRequest);

            CompleteMultipartUploadResult multipartUploadResult = uploadResult.getMultipartUploadResult();
            // System.out.println(multipartUploadResult.getETag());
            return true;
        } catch (OSSException oe) {
            log.error("断点续传到OSS失败，KEY="+key+" ERR_MSG="+oe.getErrorMessage()+"ERR_code="+oe.getErrorCode(),oe);
        } catch (ClientException ce) {
            log.error("断点续传OSS失败",ce);
        } catch (Throwable e) {
            log.error("",e);
        } finally {
        }
        return false;
    }

    /**
     * 删除文件
     * @param key 文件路径,例comfile/2016/12/1111.jpg 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @return
     */
    public static boolean  remove(String key){
        try {
            ossClient.deleteObject(bucketName, key);
        }catch (OSSException|ClientException e){
            log.warn("删除oss文件失败！ 文件KEY="+key,e);
            return false;
        }
        return true;
    }

    /**
     * 获取文件
     * @param key  文件路径,例comfile/2016/12/1111.jpg 命名规范如下：使用UTF-8编码，长度必须在1-1023字节之间，不能以“/”或者“\”字符开头。
     * @return  文件流。
     */
    public static InputStream get(String key){
        OSSObject obj  =ossClient.getObject(bucketName,key);
        return  obj.getObjectContent();
    }

    public static void main(String[] args) {
//        put("111/223/l.jpg",new File("C:\\Users\\ye\\Pictures\\1.jpg"));
        System.out.println(getUrlPath("comfile/2016/12/1111.jpg"));
        System.out.println(getKey("http://foshantest.oss-cn-shanghai.aliyuncs.com/comfile/2016/12/1111.jpg"));
        /*InputStream in=get("111/223/l.jpg");
        byte[] ba=new byte[1024];
        int i=0;
        try {
            while ( (i=in.read(ba)) > 0) {
                System.out.println(i);
            }
            in.close();
        }catch (Exception e){
            log.error("",e);
        }
*/
    }

}
